package com.liuceng.zen.web.controller;

import com.liuceng.zen.constants.Constants;
import com.liuceng.zen.web.auth.realm.ShiroDbRealm.UserContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Validator;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.util.*;

public abstract class BaseController extends MultiActionController {
  /** 错误视图 */
  protected static final String ERROR_VIEW = "redirect:/404";
  /**
   * 日志对象
   */
  protected Logger logger = LoggerFactory.getLogger(getClass());
  /**
   * 验证Bean实例对象
   */
  @Autowired
  protected Validator validator;


  /**
   * 添加Model消息
   *
   * @param messages 消息
   */
  protected void addMessage(Model model, String... messages) {
    StringBuilder sb = new StringBuilder();
    for (String message : messages) {
      sb.append(message).append(messages.length > 1 ? "<br/>" : "");
    }
    model.addAttribute("message", sb.toString());
  }

  /**
   * 添加Flash消息
   *
   * @param messages 消息
   */
  protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
    StringBuilder sb = new StringBuilder();
    for (String message : messages) {
      sb.append(message).append(messages.length > 1 ? "<br/>" : "");
    }
    redirectAttributes.addFlashAttribute("message", sb.toString());
  }

  /**
   * 初始化数据绑定 1. 将所有传递进来的String进行HTML编码，防止XSS攻击 2. 将字段中Date类型转换为String类型
   */
  @InitBinder
  protected void initBinder(WebDataBinder binder) {
    // String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
    binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
      @Override
      public void setAsText(String text) {
        setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
      }

      @Override
      public String getAsText() {
        Object value = getValue();
        return value != null ? value.toString() : "";
      }
    });
    // Date 类型转换
    binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
      @Override
      public void setAsText(String text) {
        try {
          setValue(DateUtils.parseDate(text));
        } catch (ParseException e) {
          logger.error(e.getMessage(), e);
        }
      }
    });
  }

  //

  /**
   * Jquery DataTable Data
   *
   * @param totalCount
   * @param dataList
   * @return
   */
  protected Map<String, Object> dataTableJson(int totalCount, List<?> dataList) {
    Map<String, Object> data = new HashMap<String, Object>();
    data.put("iTotalDisplayRecords", totalCount);
    data.put("iTotalRecords", totalCount);
    data.put("aaData", dataList == null ? Collections.EMPTY_LIST : dataList);
    Map<String, Object> map = new HashMap<String, Object>();
    if (CollectionUtils.isEmpty(dataList)) {
      map.put("result", Constants.ERROR);
    } else {
      map.put("result", Constants.SUCCESS);
    }
    map.put("data", data);
    return map;
  }

  protected Map<String, Object> data2json(List<?> data) {
    Map<String, Object> map = new HashMap<String, Object>();
    if (CollectionUtils.isEmpty(data)) {
      map.put("result", Constants.ERROR);
    } else {
      map.put("result", Constants.SUCCESS);
    }
    map.put("data", data);
    return map;
  }

  protected Map<String, Object> data2json(Object data) {
    Map<String, Object> map = new HashMap<String, Object>();
    if (data == null) {
      map.put("result", Constants.ERROR);
    } else {
      map.put("result", Constants.SUCCESS);
    }
    map.put("data", data);
    return map;
  }

  //
  protected UserContext getUserContext() {
    UserContext userContext = (UserContext) SecurityUtils.getSubject().getPrincipal();
    return userContext;
  }

  protected Integer getCurrentUserId() {
    if(getUserContext()==null){
      return null;
    }
    return getUserContext().getId();
  }

  // 插入操作记录监控的方法
  public void saveOptLog(HttpServletRequest request, String eventId, String eventName,
      String objectId) {

    String no = (String) WebUtils.getSessionAttribute(request, "no");
    String name = (String) WebUtils.getSessionAttribute(request, "name");

    // 插入操作记录
    /*
     * OperatorLog optLog = new OperatorLog(); optLog.setEventId(eventId);
     * optLog.setEventName(eventName); optLog.setEventTime(new Date());
     * optLog.setObjectId(objectId); optLog.setOptNo(no); optLog.setOptName(name); optLog.setIp();
     * 
     * try { this.operatorLogService.save(optLog); } catch (DataAccessException dae) { logger.error(
     * "save operatorLog failed", dae); }
     */
  }


  protected Map<String, Object> ajaxSuccess() {
    Map<String, Object> jsonMap = new HashMap<String, Object>();
    jsonMap.put("result", "ok");
    jsonMap.put("rescode", 200);
    jsonMap.put("msg", "操作成功");
    return jsonMap;
  }


  protected Map<String, Object> ajaxSuccess(Object data) {
    Map<String, Object> retMap = new HashMap<String, Object>();
    retMap.put("data", data);
    retMap.put("result", "ok");
    retMap.put("rescode", 200);
    return retMap;
  }


  protected Map<String, Object> ajaxFail() {
    Map<String, Object> jsonMap = new HashMap<String, Object>();
    jsonMap.put("result", "fail");
    jsonMap.put("msg", "系统繁忙，请稍后再试");
    return jsonMap;
  }


  protected Map<String, Object> ajaxFail(String msg) {
    Map<String, Object> jsonMap = new HashMap<String, Object>();
    jsonMap.put("result", "fail");
    jsonMap.put("msg", msg);
    return jsonMap;
  }


  protected Map<String, Object> ajaxFail(int resCode, String msg) {
    Map<String, Object> jsonMap = new HashMap<String, Object>();
    jsonMap.put("result", "fail");
    jsonMap.put("rescode", resCode);
    jsonMap.put("msg", msg);
    return jsonMap;
  }

  protected Map<String, Object> ajaxFail(String key, String msg, int resCode) {
    Map<String, Object> jsonMap = new HashMap<String, Object>();
    jsonMap.put("result", "fail");
    jsonMap.put("rescode", resCode);
    jsonMap.put(key, msg);
    return jsonMap;
  }

  protected Map<String, Object> badParamMap(String key, String msg) {
    Map<String, Object> retMap = new HashMap<String, Object>();
    retMap.put("result", "badparam");
    retMap.put("msg", "参数错误");
    Map<String, Object> data = new HashMap<String, Object>();
    data.put(key, msg);
    retMap.put("data", data);
    return retMap;
  }

}
